[CXP-204] improve rate limit and temporary error handling#121
Merged
johnallers merged 3 commits intomainfrom Feb 5, 2026
Merged
[CXP-204] improve rate limit and temporary error handling#121johnallers merged 3 commits intomainfrom
johnallers merged 3 commits intomainfrom
Conversation
WalkthroughAdds helpers to detect GitHub rate/abuse limits and temporary server errors, build RateLimitDescription from github.Rate or Retry-After durations, and attach that detail to gRPC status errors; updates wrapGitHubError to propagate these details and treat 502/503/504 as temporarily unavailable. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Connector
participant GitHubAPI
participant gRPCStatus
Client->>Connector: Request
Connector->>GitHubAPI: Call GitHub
alt RateLimitError (with Rate)
GitHubAPI-->>Connector: RateLimitError (with Rate)
Connector->>Connector: rateLimitDescriptionFromRate()
Connector->>gRPCStatus: wrapErrorWithRateLimitDetails()
gRPCStatus-->>Connector: gRPC error with RateLimitDescription
Connector-->>Client: rate-limited gRPC error
else AbuseRateLimitError (Retry-After)
GitHubAPI-->>Connector: AbuseRateLimitError (Retry-After)
Connector->>Connector: rateLimitDescriptionFromRetryAfter()
Connector->>gRPCStatus: wrapErrorWithRateLimitDetails()
gRPCStatus-->>Connector: gRPC error with RateLimitDescription
Connector-->>Client: rate-limited gRPC error
else TemporaryServerError (502/503/504)
GitHubAPI-->>Connector: 502/503/504
Connector->>Connector: isTemporarilyUnavailable()
Connector-->>Client: temporary-unavailable error
else OtherError
GitHubAPI-->>Connector: Other error
Connector-->>Client: wrapped error (existing behavior)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
7896b65 to
1498c3e
Compare
luisina-santos
approved these changes
Feb 4, 2026
When go-github blocks requests client-side due to rate limits, it returns a RateLimitError with a synthetic 403 response that has empty headers. The existing isRatelimited() check failed because it expects the X-Ratelimit-Remaining header to equal "0", but the synthetic response has no headers at all. This caused rate limit errors to be misclassified as PermissionDenied, which is not retried by the SDK. Changes: - Check for *github.RateLimitError and *github.AbuseRateLimitError types using errors.As() before checking HTTP status codes - Extract rate limit data (reset time, limit, remaining) from the error and attach it to the gRPC status details for proper backoff - Add isTemporarilyUnavailable() to handle 503, 502, and 504 errors - Return codes.Unavailable for all these cases, enabling SDK retry logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1498c3e to
b125940
Compare
FeliLucero1
reviewed
Feb 5, 2026
Prevent creating misleading timestamps when rate.Reset.Time is zero, matching the defensive pattern used in other rate limit functions. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@pkg/connector/helpers.go`:
- Line 202: The lint error comes from using the redundant embedded field
selector Time when calling IsZero on a github.Timestamp; change the check in the
rate handling code from using rate.Reset.Time.IsZero() to rate.Reset.IsZero()
(i.e., call IsZero directly on rate.Reset which embeds time.Time) so the lint
warning is resolved; update any other occurrences in the same file/function that
reference rate.Reset.Time to use rate.Reset instead.
FeliLucero1
approved these changes
Feb 5, 2026
btipling
approved these changes
Feb 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PermissionDeniedinstead ofUnavailable, causing syncs to fail instead of retry*github.RateLimitErrorand*github.AbuseRateLimitErrorerror types usingerrors.As()Unavailable(retryable)Problem
When go-github blocks requests client-side due to rate limits, it returns a
RateLimitErrorwith a synthetic 403 response that has empty headers. The existingisRatelimited()check failed because it expectsX-Ratelimit-Remainingheader to equal"0", but the synthetic response has no headers. This caused rate limit errors to be misclassified asPermissionDenied, which is not retried by the SDK.Solution
Check for go-github error types before checking HTTP status codes:
*github.RateLimitError→ extractRate.Reset,Rate.Limit,Rate.Remaining→codes.Unavailablewith rate limit details*github.AbuseRateLimitError→ useRetryAfterduration →codes.Unavailablewith rate limit detailscodes.Unavailable(retryable)The SDK's retry logic now receives proper rate limit data to calculate appropriate backoff times.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit